package cn.wolfcode.car.business.service.impl;


import cn.wolfcode.car.base.domain.User;
import cn.wolfcode.car.base.service.IUserService;
import cn.wolfcode.car.business.domain.BpmnInfo;
import cn.wolfcode.car.business.domain.CarPackageAudit;
import cn.wolfcode.car.business.domain.ServiceItem;
import cn.wolfcode.car.business.mapper.ServiceItemMapper;
import cn.wolfcode.car.business.query.ServiceItemQuery;
import cn.wolfcode.car.business.service.IBpmnInfoService;
import cn.wolfcode.car.business.service.ICarPackageAuditService;
import cn.wolfcode.car.business.service.IServiceItemService;
import cn.wolfcode.car.common.base.page.TablePageInfo;
import cn.wolfcode.car.common.exception.BusinessException;
import cn.wolfcode.car.common.util.Convert;
import cn.wolfcode.car.shiro.ShiroUtils;
import com.github.pagehelper.PageHelper;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.runtime.ProcessInstance;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
@Transactional
public class ServiceItemServiceImpl implements IServiceItemService {

    @Autowired
    private ServiceItemMapper serviceItemMapper;

    @Autowired
    private ICarPackageAuditService carPackageAuditService;
    @Autowired
    private RuntimeService runtimeService;
    @Autowired
    private IBpmnInfoService bpmnInfoService;
    @Autowired
    private IUserService userService;

    @Override
    public TablePageInfo<ServiceItem> query(ServiceItemQuery qo) {

        PageHelper.startPage(qo.getPageNum(), qo.getPageSize());
        return new TablePageInfo<ServiceItem>(serviceItemMapper.selectForList(qo));
    }


    @Override
    public void save(ServiceItem serviceItem) {
        // 1 时间没有传, 需要 自己 new 一个时间对象
        serviceItem.setCreateTime(new Date());
        // 2 新增的上架状态 需为下架状态，防止前端页面传过来上架状态的值
        serviceItem.setSaleStatus(ServiceItem.SALESTATUS_OFF);
        // 3 审核状态没传 --> 看是否是套餐，
        // 如果是套餐，则设置审核状态为初始化，如果不是套餐设置审核转态为 无须审核
        if (serviceItem.getCarPackage() == 1){
            // 套餐，--> 初始化
            serviceItem.setAuditStatus(ServiceItem.AUDITSTATUS_INIT);
        }else {
            // 非套餐  --> 无序审核
            serviceItem.setAuditStatus(ServiceItem.AUDITSTATUS_NO_REQUIRED);
        }
        serviceItemMapper.insert(serviceItem);
    }

    @Override
    public ServiceItem get(Long id) {
        return serviceItemMapper.selectByPrimaryKey(id);
    }


    @Override
    public void update(ServiceItem serviceItem) {
        // 1 根据id把去 数据库查数据 --> 获取审核状态 --> 如果是上架状态或审核状态 --> 抛异常
        ServiceItem result = serviceItemMapper.selectByPrimaryKey(serviceItem.getId());
        if (result.getSaleStatus().equals(ServiceItem.SALESTATUS_ON)
                || result.getAuditStatus().equals(ServiceItem.AUDITSTATUS_APPROVED)){
            throw new RuntimeException("非法操作");
        }
        //存在 bug， 编辑后  审核状态变为了 默认的未审核状态  -->  自己设为为其对应数据库的状态
        serviceItem.setAuditStatus(result.getAuditStatus());
        // 2 如果是套餐且审核通过状态，则把审核状态改为 初始化状态
        if (result.getCarPackage().equals(ServiceItem.CARPACKAGE_YES)
                && result.getAuditStatus().equals(ServiceItem.AUDITSTATUS_APPROVED)){
            serviceItem.setAuditStatus(ServiceItem.AUDITSTATUS_INIT);
        }
        serviceItemMapper.updateByPrimaryKey(serviceItem);
    }

    @Override
    public void deleteBatch(String ids) {
        Long[] dictIds = Convert.toLongArray(ids);
        for (Long dictId : dictIds) {
            serviceItemMapper.deleteByPrimaryKey(dictId);
        }
    }

    @Override
    public List<ServiceItem> list() {
        return serviceItemMapper.selectAll();
    }

    @Override
    public void saleOn(Long id) {
        // 1 根据id把数据从数据查出来，
        ServiceItem serviceItem = serviceItemMapper.selectByPrimaryKey(id);
        // 2 判断上架状态，如果为上架状态抛异常
        if (serviceItem.getSaleStatus().equals(ServiceItem.SALESTATUS_ON)){
            throw new RuntimeException("操作异常");
        }
        // 3 如果是套餐但是审核状态是 非审核通过，抛异常
        if (serviceItem.getCarPackage().equals(ServiceItem.CARPACKAGE_YES)
                && !serviceItem.getAuditStatus().equals(ServiceItem.AUDITSTATUS_APPROVED)){
            throw new RuntimeException("非法操作");
        }
        // 4 修改上架状态
        serviceItemMapper.updateSaleStatus(id, ServiceItem.SALESTATUS_ON);
    }

    @Override
    public void saleOff(Long id) {
        // 1 根据id把数据从数据查出来，
        ServiceItem serviceItem = serviceItemMapper.selectByPrimaryKey(id);
        // 2 判断上架状态，如果为下架状态抛异常
        if (serviceItem.getSaleStatus().equals(ServiceItem.SALESTATUS_OFF)){
            throw new RuntimeException("操作异常");
        }
        // 3 修改上架状态为下架
        serviceItemMapper.updateSaleStatus(id, ServiceItem.SALESTATUS_OFF);
    }

    @Override
    public void startAudit(Long id, Long bpmnInfoId, Long director, Long finance, String info) {
        /**  思路逻辑：
         * --判断满足审核条件（必须是套餐、初始化）、  --套餐服务状态改为“审核中”
         * --添加套餐审核记录-CarPackageAudit        -- 启动流程 --> 设置相关参数（审核人，条件变量（做判断））+ 、
         */
        // 判断满足审核条件（必须是套餐、初始化）
        ServiceItem serviceItem = serviceItemMapper.selectByPrimaryKey(id);
        if (serviceItem == null || !serviceItem.getAuditStatus().equals(ServiceItem.AUDITSTATUS_INIT)
                || !serviceItem.getCarPackage().equals(ServiceItem.CARPACKAGE_YES)){
            throw new BusinessException("服务单项必须是套餐、且初始化");
        }
        //套餐服务状态改为“审核中”
        serviceItem.setAuditStatus(ServiceItem.AUDITSTATUS_AUDITING);
        //添加套餐审核记录-CarPackageAudit
        CarPackageAudit carPackageAudit = new CarPackageAudit();
        carPackageAudit.setServiceItemId(id);
        carPackageAudit.setServiceItemInfo(serviceItem.getInfo());
        carPackageAudit.setServiceItemPrice(serviceItem.getDiscountPrice());
        // carPackageAudit.setInstanceId(); // 部署后再完成 --> 更新
        carPackageAudit.setCreator(ShiroUtils.getUser().getLoginName()); // 创建者
        carPackageAudit.setAuditorId(director);
        carPackageAudit.setBpmnInfoId(bpmnInfoId);
        carPackageAudit.setInfo(info);
        // 状态设置为 "审核中"
        carPackageAudit.setStatus(CarPackageAudit.STATUS_IN_ROGRESS);
        // carPackageAudit.setAuditTime(); // 最后审核时间
        carPackageAudit.setCreateTime(new Date());
        // 保存 --> 添加套餐审核记录-CarPackageAudit
        carPackageAuditService.save(carPackageAudit);

        // *********************** 启动流程实例 ********************************
        // 设置相关参数（审核人，条件变量（做判断））
        BpmnInfo bpmnInfo = bpmnInfoService.get(bpmnInfoId);
        String processDefinitionKey = bpmnInfo.getActProcessKey(); // 获取流程定义的key
        String businessKey = carPackageAudit.getId().toString(); // 获取业务表的id businessKey
        Map<String, Object> map = new HashMap<>();
        // 注意：activiti 不支持 BigDecimal ----> 转为Long
        map.put("discountPrice", serviceItem.getDiscountPrice().longValue());
        if (director != null){
//            User user = userService.get(director);
//            map.put("director", user.getUserName());  // 不能这样写
            map.put("director", director);
        }
        if (finance != null){
//            User user = userService.get(finance);
//            map.put("finance", user.getUserName()); // 不能这样写
            map.put("finance", finance);
        }
        // 启动流程实例    参数1：流程定义的key 在bpmnInfo表中 参数2(String类型)：套餐审核业务表的id
        ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(processDefinitionKey, businessKey, map);

        // 跟新套餐审核记录的 流程部署id (上面之前没部署，没有设置部署id)
        carPackageAuditService.updateProcessInstanceId(carPackageAudit.getId(), processInstance.getId());
    }

    @Override
    public void changeAuditStatus(Long serviceItemId, Integer auditstatusInit) {
        serviceItemMapper.changeAuditStatus(serviceItemId, auditstatusInit);
    }

    @Override
    public void updateAuditStatus(Long serviceItemId, Integer auditstatusApproved) {
        serviceItemMapper.changeAuditStatus(serviceItemId, auditstatusApproved);
    }

}
